/**
*	Class: Cache
*
*	The Cache object is used to store the users minitransactions (also acting as a buffer).
*	It has an automatic checking of when it has to flush the minitransaction cached, and avoid send unecessary or overriden data.
*
*	@param maxSize - the max number of minitransactions stored without calling the flush event
*	@param flushEvent - the action peformed when the cache/buffer needs to flush the minitrasactions cached
*/
function Cache(maxSize, flushEvent){

	// Cache storing spaces
	this._newProjects = new Array(0);
	this._alterProjects = new Array(0);
	this._remProjects = new Array(0);

	this._newPosts = new Array(0);
	this._alterPosts = new Array(0);
	this._remPosts = new Array(0);

	this._alterContainer = new Array(0);
	
	// Handling attributes
	this._flushEvent = flushEvent;
	this._maxSize = maxSize;
	this._elementCount = 0;

	if(typeof Cache.prototype._initialized == "undefined"){
	
		/**
		*	Adds a NewProject minitransaction.
		*
		*	@param project - the created project 
		*/
		Cache.prototype.newProject = function(project){
			this._newProjects[newProject.getId()] = new NewProject(project);
			this.pooling();
		};
		
		/**
		*	Adds an AlterProject minitransaction.
		*
		*	@param project - the modified project 
		*/
		Cache.prototype.alterProject = function(project){
			this._alterProjects[alterProject.getId()] = new AlterProject(project);
			this.pooling();
		};		

		/**
		*	Adds a RemProject minitransaction.
		*
		*	@param projectId - the id from the removed project
		*/
		Cache.prototype.remProject = function(projectId){
			this._remProjects.push(new RemoveProject(projectId));
			this.pooling();
		};

		/**
		*	Adds a NewPost minitransaction.
		*
		*	@param postIt - the added post-it 
		*	@param containerId - the container's id which the post-it belongs to
		*	@param projectId - the project's id which the post-it belongs to
		*/
		Cache.prototype.newPost = function(postIt, containerId, projectId){
			this._newPosts[newPost.getId()] = new NewPostIt(postIt, projectId, containerId);
			this.pooling();
		};

		/**
		*	Adds an AlterPost minitransaction.
		*
		*	@param postIt - the modified post-it 
		*	@param projectId - the project's id which the post-it belongs to
		*/
		Cache.prototype.alterPost = function(postIt, projectId){
			this._alterPosts[alterPost.getId()] = new AlterPostIt(postIt, projectId);
			this.pooling();
		};

		/**
		*	Adds a RemPost minitransaction.
		*
		*	@param postId - the id from the removed post-it
		*	@param projectId - the project's id which the post-it belongs
		*/
		Cache.prototype.remPost = function(postId, projectId){
			this._remPosts.push( new RemovePostIt(postId, projectId) );
			this.pooling();
		};		
		
		/**
		*	Adds an AlterContainer minitransaction.
		*
		*	@param alterContainer - NewPost minitransaction
		*/
		Cache.prototype.alterContainer = function(postId, projectId, oldContainer, newContainer){
			this._alterContainer.push( new AlterContainer(remPostId, projectId, oldContainer, newContainer) );
			this.pooling();
		};		
		
		/**
		*	@private	
		*
		*	Pooling routine called everytime when the cache/buffer mintransactions data is inserted. This routine beyond update the cache/buffer status,
		*	it also checks if a flush is necessary. If it is, then the flush event is called. 
		*/
		Cache.prototype.pooling = function(){
			this._elementCount += 1;
			if(this.flushPolicy()){
				this._flushEvent();
			}
		};
		
		/**
		*	@private
		*
		*	Checks if the cache/buffer, by it's current status, needs a flush operation.
		*
		*	@return boolean - true if it needs to be flushed, false if it does not
		*/
		Cache.prototype.flushPolicy = function(){
			return this._elementCount > this._maxSize;
		}

		/**
		*	Generates the XML of all the consistent minitransactions to communicate with the app. server.
		*
		*	@return String - the set of mintransactions in xml document format
		*/
		Cache.prototype.genXML = function(){
			var alterationsMade = String("<action>"); // Inicial tag
			
			var id; //Auxiliar variable
			
			// Alter Container
			for(id in this._alterContainer){
				alterationsMade += this._alterContainer[id].genXML();			
			}
			
			// New Posts
			for(id in this._newPosts){
				alterationsMade += this._newPosts[id].genXML();
			}

			// Altered Posts
			for(id in this._alterPosts){
				alterationsMade += this._alterPosts[id].genXML();
			}

			// Removed Posts
			for(id in this._remPosts){
				alterationsMade += this._remPosts[id].genXML();
			}

			// New Projects
			for(id in this._newProjects){
				alterationsMade += this._newProjects[id].genXML();
			}

			// Altered Projects
			for(id in this._alterProjects){
				alterationsMade += this._alterProjects[id].genXML();
			}

			// Removed Projects
			for(id in this._remProjects){
				alterationsMade += this._remProjects[id].genXML();
			}

			alterationsMade += "</action>"; // Final tag
		
			return alterationsMade;
		};

		/**
		*	Clears the content of the cache/buffer and reset it's status.
		*/
		Cache.prototype.clear = function(){
			this._newProjects = new Array(0);
			this._alterProjects = new Array(0);
			this._remProjects = new Array(0);

			this._newPosts = new Array(0);
			this._alterPosts = new Array(0);
			this._remPosts = new Array(0);

			this._alterContainer = new Array(0);
			
			this._elementCount = 0;
		};
		
		Cache.prototype._initialized = true;
	}

}

